package com.rxt.thermopro.ex

import android.app.Service
import android.content.Context
import android.media.AudioAttributes
import android.media.MediaPlayer
import android.media.SoundPool
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import com.rxt.thermopro.R
import com.rxt.thermopro.app.AppContext
import com.rxt.thermopro.app.LocalDataDao


class ActionSound {
    private var pid = -1
    private var vPid = -1
    private var soundPool: SoundPool? = null
    private var vibrator: Vibrator? = null
    private var loadFinished = false
    private var streamId = -1
    private val streamIdMap = hashMapOf<String, Int>()

    private var mMediaPlayer: MediaPlayer? = null

    private fun getSoundPool(): SoundPool {
        if (soundPool == null) {
            soundPool = SoundPool.Builder().build()
        }
        return soundPool!!
    }

    private fun getVibrator(): Vibrator {
        if (vibrator == null) {
            vibrator = AppContext.get().getSystemService(Service.VIBRATOR_SERVICE) as Vibrator?
        }
        return vibrator!!
    }

    fun alarm(context: Context) {
        val sound = getSoundPool()
        if (LocalDataDao.INSTANCE.isAlarmVibration()) {
            val mVibrator = getVibrator()
            mVibrator.vibrate(longArrayOf(1000L, 2000L, 1000L, 2000L), 0)
        }
        if (LocalDataDao.INSTANCE.isAlarm()){
            if (pid == -1) {
                loadFinished = false
                pid = sound.load(context, R.raw.h, 0)
                sound.setOnLoadCompleteListener { _, _, _ ->
                    loadFinished = true
                    streamId = sound.play(pid, 1f, 1f, 1, -1, 1f)
                }
            }
            if (loadFinished) {
                streamId = sound.play(pid, 1f, 1f, 1, -1, 1f)
                return
            }
        }
    }

    fun alarm(context: Context, address: String) {
        val sound = getSoundPool()
        if (LocalDataDao.INSTANCE.isAlarmVibration(address)) {
            val mVibrator = getVibrator()
            val  audioAttributes = AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_ALARM) //key
                .build()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mVibrator.vibrate(
                    VibrationEffect.createWaveform(
                        longArrayOf(
                            1000L,
                            2000L,
                            1000L,
                            2000L
                        ), 0
                    ),audioAttributes
                )
            } else {
                mVibrator.vibrate(longArrayOf(1000L, 2000L, 1000L, 2000L), 0,audioAttributes)
            }
        }
        if (LocalDataDao.INSTANCE.isAlarm(address)){
            if (pid == -1) {
                loadFinished = false
                pid = sound.load(context, R.raw.h, 0)
                sound.setOnLoadCompleteListener { _, _, _ ->
                    loadFinished = true
                    streamIdMap[address] = sound.play(pid, 1f, 1f, 1, -1, 1f)
                }
            }
            if (loadFinished) {
                streamIdMap[address] = sound.play(pid, 1f, 1f, 1, -1, 1f)
                return
            }
        }
    }


    fun alarm(context: Context, probeIndex: Int, address: String) {
        if (LocalDataDao.INSTANCE.isAlarmVibration(address)) {
            val mVibrator = getVibrator()
            val  audioAttributes = AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_ALARM) //key
                .build()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mVibrator.vibrate(
                    VibrationEffect.createWaveform(
                        longArrayOf(
                            1000L,
                            2000L,
                            1000L,
                            2000L
                        ), 0
                    ),audioAttributes
                )
            } else {
                mVibrator.vibrate(longArrayOf(1000L, 2000L, 1000L, 2000L), 0,audioAttributes)
            }
        }

        if (LocalDataDao.INSTANCE.isAlarm(address)){
            val currentIndex = when (probeIndex) {
                0 -> {
                    LocalDataDao.INSTANCE.getProbeAlarm1(address)
                }
                1 -> {
                    LocalDataDao.INSTANCE.getProbeAlarm2(address)
                }
                2 -> {
                    LocalDataDao.INSTANCE.getProbeAlarm3(address)
                }
                3 -> {
                    LocalDataDao.INSTANCE.getProbeAlarm4(address)
                }
                else -> LocalDataDao.INSTANCE.getProbeAlarm1(address)
            }
            if (currentIndex == 0) {
                val sound = getSoundPool()
                if (pid == -1) {
                    loadFinished = false
                    pid = sound.load(context, R.raw.h, 0)
                    sound.setOnLoadCompleteListener { _, _, _ ->
                        loadFinished = true
                        streamIdMap[address] = sound.play(pid, 1f, 1f, 1, -1, 1f)
                    }
                }
                if (loadFinished) {
                    streamIdMap[address] = sound.play(pid, 1f, 1f, 1, -1, 1f)
                    return
                }
            } else {
                if (mMediaPlayer?.isPlaying == true) {
                    mMediaPlayer?.stop()
                }
                mMediaPlayer = MediaPlayer.create(
                    AppContext.get(),
                    LocalDataDao.INSTANCE.getProbeAlarmList()[currentIndex].ringUri
                )
                mMediaPlayer?.isLooping = true
                mMediaPlayer?.start()
            }
        }
    }

    fun stop(context: Context, probeIndex: Int, address: String) {
        if (LocalDataDao.INSTANCE.isAlarmVibration(address)) {
            val mVibrator = getVibrator()
            mVibrator.cancel()
        }

        val currentIndex = when (probeIndex) {
            0 -> {
                LocalDataDao.INSTANCE.getProbeAlarm1(address)
            }
            1 -> {
                LocalDataDao.INSTANCE.getProbeAlarm2(address)
            }
            2 -> {
                LocalDataDao.INSTANCE.getProbeAlarm3(address)
            }
            3 -> {
                LocalDataDao.INSTANCE.getProbeAlarm4(address)
            }
            else -> LocalDataDao.INSTANCE.getProbeAlarm1(address)
        }
        if (currentIndex == 0) {
            val sound = getSoundPool()
            streamIdMap[address]?.let {
                if (streamIdMap[address] != -1) {
                    sound.stop(it)
                }
            }
        } else {
            mMediaPlayer?.stop()
        }
    }

    fun stop(context: Context, address: String) {
        val sound = getSoundPool()
        streamIdMap[address]?.let {
            if (streamIdMap[address] != -1) {
                sound.stop(it)
            }
        }
        if (LocalDataDao.INSTANCE.isAlarmVibration()) {
            val mVibrator = getVibrator()
            mVibrator.cancel()
        }
        if (mMediaPlayer?.isPlaying == true) {
            mMediaPlayer?.stop()
        }
    }

    fun stop(context: Context) {
        val sound = getSoundPool()
        streamIdMap.keys.forEach {
            streamIdMap[it]?.let { item ->
                if (item != -1) {
                    sound.stop(item)
                }
            }
        }

        if (LocalDataDao.INSTANCE.isAlarmVibration()) {
            val mVibrator = getVibrator()
            mVibrator.cancel()
        }
        if (mMediaPlayer?.isPlaying == true) {
            mMediaPlayer?.stop()
        }
    }

    fun rec(context: Context) {
        val sound = getSoundPool()
        if (vPid == -1) {
            loadFinished = false
            vPid = sound.load(context, R.raw.h, 0)
            sound.setOnLoadCompleteListener { _, _, _ ->
                loadFinished = true
                streamId = sound.play(vPid, 1f, 1f, 1, -1, 1f)
            }
        }
        if (loadFinished) {
            streamId = sound.play(vPid, 1f, 1f, 1, -1, 1f)
            return
        }
    }

    fun release() {
        streamId = -1
        soundPool?.release()
    }
}